package com.budwk.app.fastDfs.service.impl;

import cn.hutool.core.io.resource.InputStreamResource;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.base.utils.nutzBeanUtils.NutzIocUtils;
import com.budwk.app.fastDfs.service.FastDfsService;
import com.budwk.app.miniapp.common.enums.WxEventEnum;
import com.budwk.app.oss.models.SysOss;

import com.budwk.app.sys.models.ShequUser;
import com.budwk.starter.common.exception.BaseException;
import com.budwk.starter.common.result.Result;
import com.budwk.starter.database.service.BaseServiceImpl;
import com.budwk.starter.security.utils.SecurityUtil;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.ioc.impl.PropertiesProxy;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.mvc.upload.TempFile;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author ZY.Wang
 * @since 2024/3/6
 */
@Slf4j
@IocBean(args = {"refer:dao"})
public class FastDfsServiceImpl extends BaseServiceImpl<SysOss> implements FastDfsService {

    private String fastDfsIpStr;

    @Inject
    private PropertiesProxy propertiesProxy;

    public FastDfsServiceImpl(Dao dao) {
        super(dao);
    }

    //--通过TempFile文件上传----------------------------------------------------------------
    @Override
    public SysOss upload(TempFile file) {
        return upload(file, null, true);
    }

    @Override
    public SysOss upload(TempFile file, String fileName) {
        return upload(file, fileName, true);
    }

    @Override
    public SysOss uploadNotUUID(TempFile file, String fileName) {
        return upload(file, fileName, false);
    }

    @Override
    public SysOss upload(TempFile file, String fileName, boolean uuidFlag) {
        String originalFileName = file.getSubmittedFileName();

        String suffix = StringUtils.substring(originalFileName, originalFileName.lastIndexOf("."), originalFileName.length());
        fileName = getFileName(suffix, fileName, uuidFlag);
        String filePath = getFilePath();
        System.out.println("生成的文件路径" + filePath);

        String url = uploadTOFastDFS(file.getFile(), filePath, fileName);

        return insertSysOss(url, suffix, fileName, fileName);
    }

    //--通过字节流上传文件--------------------------------------------------------------------
    @Override
    public SysOss upload(byte[] bytes, String fileName) {
        return upload(bytes, fileName, true);
    }

    @Override
    public SysOss upload(byte[] bytes, String fileName, boolean uuidFlag) {
        if (StringUtils.isBlank(fileName)) return null;
        int lastSymbolIndex = fileName.lastIndexOf(".");
        if (lastSymbolIndex == fileName.length() - 1) return null;

        String suffix = fileName.substring(lastSymbolIndex + 1);

        fileName = getFileName(suffix, fileName, true);
        String filePath = getFilePath();

        String url = uploadTOFastDFS(bytes, filePath, fileName);

        return insertSysOss(url, suffix, fileName, fileName);
    }

    //--通过File上传-------------------------------------------------------------------------
    @Override
    public SysOss upload(File file) {
        return upload(file, null, false);
    }

    @Override
    public SysOss upload(File file, String fileName) {
        return upload(file, fileName, false);
    }

    @Override
    public SysOss upload(File file, String fileName, boolean uuidFlag) {
        String originalFileName = file.getName();

        String suffix = StringUtils.substring(originalFileName, originalFileName.lastIndexOf("."), originalFileName.length());
        String path = getFilePath();
        fileName = getFileName(suffix, fileName, uuidFlag);

        String url = uploadTOFastDFS(file, path, fileName);

        return insertSysOss(url, suffix, fileName, fileName);
    }

    //--------------------------------------------------------------------------
    //---------------------私有方法----------------------------------------------
    //--------------------------------------------------------------------------

    private String uploadTOFastDFS(File file, String path, String fileName) {
        String getJwtTokenUrl= com.budwk.app.miniapp.utils.NutzIocUtils.getPropertiesProxy().get("app.getJwtToken");
        String genTokenByPhoneUrl= com.budwk.app.miniapp.utils.NutzIocUtils.getPropertiesProxy().get("app.genTokenByPhone");
        HashMap<String, Object> paramMap = new HashMap<>();
        Result result = JSONUtil.toBean(HttpUtil.post(getJwtTokenUrl, paramMap),Result.class);
        if(!result.isSuccess()){
           throw new BaseException(result.toString());
        }
        String jwtToken= (String) result.getData();
        paramMap.put("phone", "18984058233");
        paramMap.put("jwtToken",jwtToken);
        Result result2 = JSONUtil.toBean(HttpUtil.post(genTokenByPhoneUrl, paramMap),Result.class);
        if(!result2.isSuccess()){
            throw new BaseException(result2.toString());
        }
        String token= (String) result2.getData();
        Map<String, Object> params = Maps.newHashMap();
        params.put("file", file);

        params.put("filename", fileName);
        params.put("output", "json");
        params.put("auth_token", token);
        String resStr = HttpUtil.post(getFastDfsUploadUrl(), params);
        return getUrlFromFastDFSRes(resStr);
    }

    private String uploadTOFastDFS(byte[] bytes, String path, String fileName) {
        Map<String, Object> params = Maps.newHashMap();
        InputStreamResource isr = new InputStreamResource(new ByteArrayInputStream(bytes), fileName);
        params.put("file", isr);
        // wzy 2024-3-18 我们自己不添加路径了
        // params.put("path", path);
        params.put("filename", fileName);
        params.put("output", "json");
        params.put("auth_token", NutzIocUtils.tokenForFastDFSFile);
        String resStr = HttpUtil.post(getFastDfsUploadUrl(), params);
        System.out.println("pdf上传返回的路径我瞅瞅:" + resStr);
        return getUrlFromFastDFSRes(resStr);
    }

    /**
     * 获取文件名称
     *
     * @param suffix 文件后缀
     * @return 文件名
     */
    private String getFileName(String suffix, String fileName, boolean uuidFlag) {
        String newFileName = "";
        if (StringUtils.isBlank(fileName)) {
            suffix = suffix.replace(".", "");    // 为了保证数据统一，传入的所有的后缀名都先去掉.
            if (uuidFlag) newFileName += IdUtil.fastSimpleUUID();
        } else {
            suffix = suffix.replace(".", ""); // 传入的后缀需要去掉.

            int suffixIndex = fileName.lastIndexOf(suffix);
            newFileName = fileName.substring(0, suffixIndex - 1);
            if (uuidFlag) newFileName += "-" + IdUtil.fastSimpleUUID();
        }
        return newFileName + "." + suffix;
    }

    private String getFilePath() {
        return new SimpleDateFormat("yyyy/MM/dd").format(new Date()) + "/";
    }

    private String getUrlFromFastDFSRes(String resStr) {
        if (StringUtils.isNotBlank(resStr)) {
            JSONObject resJsonObj = JSONObject.parseObject(resStr);
            return resJsonObj.getString("path");
        }

        return null;
    }

    private SysOss insertSysOss(String url, String suffix, String fileName, String originalFileName) {
        SysOss oss = new SysOss();
        oss.setOssId(IdUtil.getSnowflakeNextId());
        oss.setUrl(url);
        oss.setFileSuffix(suffix);
        oss.setFileName(fileName);
        oss.setOriginalName(originalFileName);
        oss.setService("fastDFS");
        oss.setCreateTime(new Date());
        oss.setUpdateTime(new Date());
        insert(oss);
        return oss;
    }

    public String getFastDfsUploadUrl() {
        String ip = propertiesProxy.get("fastDfs.ip");
        String rest = propertiesProxy.get("fastDfs.uploadRest");

        if (ip.endsWith("/")) ip = ip.substring(0, ip.length() - 1);
        if (!rest.startsWith("/")) rest = "/" + rest;
        return ip + rest;
    }
}
